package com.xc.stock.utils;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.ContextLoader;

import com.ag.exception.SysTipsException;
import com.ag.utils.DateUtils;
import com.ag.utils.Jsons;
import com.ag.utils.NumberUtils;
import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.xc.pojo.SiteSetting;
import com.xc.pojo.User;
import com.xc.service.ISiteSettingService;
import com.xc.stock.constant.RoleEnum;
import com.xc.stock.dto.model.DestInfo;
import com.xc.utils.PropertiesUtil;
import com.xc.utils.redis.CookieUtils;
import com.xc.utils.redis.JsonUtil;
import com.xc.utils.redis.RedisShardedPoolUtils;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 * title: Utils.java
 *
 * @author rplees
 * @email rplees.i.ly@gmail.com
 * @version 1.0
 * @created Jun 11, 2023 8:35:22 PM
 */
@Slf4j
public class Utils {
	
	public static Date calcSettlementDate(String string) {
		if(StringUtils.startsWithIgnoreCase(string, "D")) { //D1
			int v = NumberUtils.parseInt(StringUtils.replaceIgnoreCase(string, "D", ""), 0);
			
			return DateUtils.dayAdd(v);
		} else if(StringUtils.startsWithIgnoreCase(string, "T")) { //D1
			int v = NumberUtils.parseInt(StringUtils.replaceIgnoreCase(string, "T", ""), 0);
			DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
			//1 ~ 7
			int value = dayOfWeek.getValue();
			
			//交易日是一周5天, 有N个周就多加 N * 2(周六, 周日)
			int add = ((((value - 1) + v) / 5) * 2) + v;
			log.info("dayOfWeek: {}, string: {}, add: {}", dayOfWeek, string, add);
			
			return DateUtils.dayAdd(v);
		} else {
			log.warn("格式不正确: {}" , string);
		}
		
		return null;
	}
	
	public static ExTrans t() {
		return ExTrans.of();
	}
	
	public static DestInfo userDestInfo(User user) {
		return DestInfo.builder()
				.id(String.valueOf(user.getId()))
				.name(user.getNickName())
				.phone(user.getPhone())
				.re(RoleEnum.USER)
				.build();
	}
	
	public static <T> T getBean(Class<T> clazz) {
		ApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext();
		return ctx.getBean(clazz);
	}

	public static boolean enableScheduled() {
		Env of = Env.of();
		return of.enabledScheduled();
	}

	/**
	 * 
	 * @param v1 格式 1.0.9
	 * @param v2
	 * @return
	 */
	public static boolean highVersion(String v1, String v2) {
		int v1Int = NumberUtils.parseInt(StringUtils.replace(v1, ".", ""));
		int v2Int = NumberUtils.parseInt(StringUtils.replace(v2, ".", ""));

		return v1Int > v2Int;
	}

	public static User getCurrentUser(HttpServletRequest request) {
		String loginToken = request.getHeader("token");
		if (StringUtils.isBlank(loginToken)) { // 优先Header
			loginToken = CookieUtils.readLoginToken(request, PropertiesUtil.getProperty("user.cookie.name"));
		}
		String userJson = RedisShardedPoolUtils.get(loginToken);
		return (User) JsonUtil.string2Obj(userJson, User.class);
	}

	/**
	 * 手机号验证
	 * 
	 * @author ：shijing 2016年12月5日下午4:34:46
	 * @param str
	 * @return 验证通过返回true
	 */
	public static boolean isMobile(final String str) {
		Pattern p = null;
		Matcher m = null;
		boolean b = false;
		p = Pattern.compile("^[1][0,1,2,3,4,5,6,7,8,9][0-9]{9}$"); // 验证手机号
		m = p.matcher(str);
		b = m.matches();
		return b;
	}

	static LoadingCache<String, SiteSetting> siteSettingCaches = CacheBuilder.newBuilder().maximumSize(100)
			.expireAfterWrite(1, TimeUnit.MINUTES).build(new CacheLoader<String, SiteSetting>() {
				@Override
				public SiteSetting load(String key) throws Exception {
					ISiteSettingService siteSettingService = SpringUtils.getBean(ISiteSettingService.class);
					return siteSettingService.getSiteSetting();
				}
			});

	public static List<String> marketServerList() {
		try {
			SiteSetting siteSetting = siteSettingCaches.get("___");
			String marketServerList = siteSetting.getMarketServerList();
			log.info("配置信息marketServerList: {}", marketServerList);
			return Jsons.toList(marketServerList, String.class);
		} catch (ExecutionException e) {
			e.printStackTrace();
			log.error("获取配置失败", e);
		}

		return Lists.newArrayList();
	}

	public static String getHqSinaStock(String stockGid) {
		String url = "/api/hq/stock/getRawSinaStock.do?stockGid=" + stockGid;
		JSONObject json = proxy(url, "GET", null, null, marketServerList());
		return json.getString("data");
	}
	
	public static JSONObject proxy(String marketUri, String method, String queryString, String body,
			List<String> list) {
		String finallyRepsonseString = null;
		int finallyStatus = 0;
		for (String marketServer : list) {
			String targetUrl = marketServer + marketUri;
			if (StringUtils.isNotBlank(queryString)) {
				targetUrl += "?" + queryString;
			}

			HttpRequest hr = new HttpRequest(targetUrl).method(Method.valueOf(StringUtils.upperCase(method)))
//						.addHeaders(Maps.transformValues(RequestUtils.getRequestHeaders(request), val -> val.toString()))
			;
			if (StringUtils.isNotBlank(body)) {
				hr.body(body);
			}

			log.info("targetUrl: {}, body: {}", targetUrl, body);
			HttpResponse execute = hr.execute();
			String responseString = execute.body();
			log.info("responseString: {}", responseString);
			finallyStatus = execute.getStatus();
			if (execute.getStatus() != 200) {
				log.info("httpStatus:{}:非200状态码", finallyStatus);
				break;
			}
			// 判断是否成功 {status == 0}
			JSONObject json = Jsons.toJSONAnyway(responseString);
			if (NumberUtils.equals(json.getInteger("status"), 0) || NumberUtils.equals(json.getInteger("code"), 0)) {
				log.info("找到数据:{}", responseString);
				finallyRepsonseString = responseString;
				break;
			} else {
				log.info("非正常返回, 跳过");
				continue;
			}
		}

		if (StringUtils.isNotBlank(finallyRepsonseString)) {
			return Jsons.toJSON(finallyRepsonseString);
		} else {
			if (finallyStatus != 200) {
				throw new SysTipsException("调用失败, 无可用服务, HttpStatus:" + finallyStatus + "!");
			}

			throw new SysTipsException("调用失败, 无可用服务!");
		}
	}

	public static void main(String[] args) {
		System.out.println(isMobile("11111111111"));
		System.out.println(isMobile("01111111111"));
		System.out.println(isMobile("111111111112"));
		System.out.println(isMobile("1111111111a"));
		
		System.out.println(DateUtils.format(calcSettlementDate("T7")));
	}
}
